package com.ansion.utils.file;

import android.text.TextUtils;

import androidx.annotation.NonNull;

import com.ansion.basetool.preconditions.Preconditions;

import java.io.File;
import java.util.HashMap;


public class FileMimeTypes {
    // compressed file format
    public static final String MIME_COMPRESS_ZIP = "application/zip";
    public static final String MIME_COMPRESS_GZIP = "application/gzip";
    public static final String MIME_COMPRESS_TGZ = "application/tgz";
    public static final String MIME_COMPRESS_7Z = "application/x-7z-compressed";
    public static final String MIME_COMPRESS_RAR = "application/vnd.rar";

    // image file formats
    public static final String MIME_IMAGE_PNG = "image/png";
    public static final String MIME_IMAGE_GIF = "image/gif";
    public static final String MIME_IMAGE_JPEG = "image/jpeg";
    public static final String MIME_IMAGE_JPG = "image/jpg";
    public static final String MIME_IMAGE_BMP = "image/bmp";

    // audio file formats
    public static final String MIME_AUDIO_MPEG = "audio/mpeg";
    public static final String MIME_AUDIO_MP3 = "audio/mp3";
    public static final String MIME_AUDIO_M4A = "audio/m4a";
    public static final String MIME_AUDIO_WAV = "audio/wav";
    public static final String MIME_AUDIO_MIDI = "audio/midi";

    // audio file formats
    public static final String MIME_VIDEO_MP4 = "video/mp4";
    public static final String MIME_VIDEO_3GPP = "video/3gpp";

    // text file formats
    public static final String MIME_DOC_TEXT_PLAIN = "text/plain";

    // other doc file formats
    public static final String MIME_DOC_APK = "application/vnd.android.package-archive";
    public static final String MIME_DOC_PDF = "application/pdf";
    public static final String MIME_DOC_CHM = "application/x-chm";
    public static final String MIME_DOC_MS_PPT = "application/vnd.ms-powerpoint";
    public static final String MIME_DOC_MS_WORD = "application/msword";
    public static final String MIME_DOC_MS_EXCEL = "application/vnd.ms-excel";
    public static final String MIME_DOC_XML = "application/xml";

    // binary data
    public static final String MIME_OCTET_STREAM = "application/octet-stream";

    private static final HashMap<String, String> mimeTypeMapping = new HashMap<>();
    private static final HashMap<String, String> extMapping = new HashMap<>();

    static {
        // compressed file formats
        addMimeExtMapping("zip", MIME_COMPRESS_ZIP);
        addMimeExtMapping("gzip", MIME_COMPRESS_GZIP);
        addMimeExtMapping("tgz", MIME_COMPRESS_TGZ);
        addMimeExtMapping("7z", MIME_COMPRESS_7Z);
        addMimeExtMapping("rar", MIME_COMPRESS_RAR);

        // image file formats
        addMimeExtMapping("png", MIME_IMAGE_PNG);
        addMimeExtMapping("gif", MIME_IMAGE_GIF);
        addMimeExtMapping("jpg", MIME_IMAGE_JPEG, MIME_IMAGE_JPG);
        mimeTypeMapping.put("jpeg", MIME_IMAGE_JPEG); // extra ext
        addMimeExtMapping("bmp", MIME_IMAGE_BMP);

        // audio file formats
        addMimeExtMapping("mp3", MIME_AUDIO_MPEG, MIME_AUDIO_MP3);
        addMimeExtMapping("m4a", MIME_AUDIO_M4A);
        addMimeExtMapping("wav", MIME_AUDIO_WAV);
        addMimeExtMapping("midi", MIME_AUDIO_MIDI);

        // audio file formats
        addMimeExtMapping("mp4", MIME_VIDEO_MP4);
        addMimeExtMapping("3gpp", MIME_VIDEO_3GPP);

        // text file formats
        addMimeExtMapping("txt", MIME_DOC_TEXT_PLAIN);
        mimeTypeMapping.put("log", MIME_DOC_TEXT_PLAIN);
        // programming languages
        mimeTypeMapping.put("c", MIME_DOC_TEXT_PLAIN);
        mimeTypeMapping.put("cpp", MIME_DOC_TEXT_PLAIN);
        mimeTypeMapping.put("cc", MIME_DOC_TEXT_PLAIN);
        mimeTypeMapping.put("java", MIME_DOC_TEXT_PLAIN);
        mimeTypeMapping.put("kt", MIME_DOC_TEXT_PLAIN);
        mimeTypeMapping.put("py", MIME_DOC_TEXT_PLAIN);
        mimeTypeMapping.put("js", MIME_DOC_TEXT_PLAIN);
        mimeTypeMapping.put("html", MIME_DOC_TEXT_PLAIN);

        // other doc file formats
        addMimeExtMapping("apk", MIME_DOC_APK);
        addMimeExtMapping("pdf", MIME_DOC_PDF);
        addMimeExtMapping("chm", MIME_DOC_CHM);
        addMimeExtMapping("pptx", MIME_DOC_MS_PPT);
        mimeTypeMapping.put("ppt", MIME_DOC_MS_PPT); // extra ext
        addMimeExtMapping("docx", MIME_DOC_MS_WORD);
        mimeTypeMapping.put("doc", MIME_DOC_MS_WORD); // extra ext
        addMimeExtMapping("xlsx", MIME_DOC_MS_EXCEL);
        mimeTypeMapping.put("xls", MIME_DOC_MS_PPT); // extra ext
        addMimeExtMapping("xml", MIME_DOC_XML);
    }

    private static void addMimeExtMapping(@NonNull String ext, @NonNull String... mimeTypes) {
        // first MIME type is the "more" official one
        mimeTypeMapping.put(ext, mimeTypes[0]);
        for (String mime : mimeTypes) {
            extMapping.put(mime, ext);
        }
    }

    /**
     * Returns the corresponding MIME type to the given extension.
     * If no MIME type was found it returns 'application/octet-stream' type.
     */
    @NonNull
    public static String getExtMimeType(@NonNull String ext) {
        if (TextUtils.isEmpty(ext)) {
            return MIME_OCTET_STREAM;
        }
        String mimeType = mimeTypeMapping.get(ext.toLowerCase());
        if (mimeType == null) {
            mimeType = MIME_OCTET_STREAM;
        }
        return mimeType;
    }

    /**
     * Returns the corresponding MIME type for the file.
     * If no MIME type was found it returns 'application/octet-stream' type.
     */
    @NonNull
    public static String getFileMimeType(@NonNull String fileName) {
        String extension = FileUtils.extensionName(fileName);
        return getExtMimeType(extension);
    }

    /**
     * Returns the default Ext to the given MimeType.
     * If no MIME type was found it returns 'unknown' ext.
     */
    @NonNull
    public static String getDefaultExt(@NonNull String mimeType) {
        Preconditions.checkNotEmpty(mimeType);
        String ext = extMapping.get(mimeType.toLowerCase());
        if (ext == null) {
            ext = "unknown";
        }
        return ext;
    }

    public static String getMimeTypeForIntent(@NonNull File file) {
        String extension = FileUtils.extensionName(file.getName());
        if (TextUtils.isEmpty(extension)) {
            return "*/*";
        }
        String mimeType = mimeTypeMapping.get(extension);
        if (TextUtils.isEmpty(mimeType)) {
            return "*/*";
        }
        return mimeType;
    }

    public static String getPictureDownloadMime(String format) {
        switch (format.toLowerCase()) {
            case "gif":
                return "image/gif";
            default:
                return "image/jpeg";
        }
    }

    public static boolean isImage(String name) {
        String format = getFileMimeType(name);
        switch (format.toLowerCase()) {
            case MIME_IMAGE_PNG:
            case MIME_IMAGE_GIF:
            case MIME_IMAGE_JPEG:
            case MIME_IMAGE_JPG:
            case MIME_IMAGE_BMP:
                return true;
        }
        return false;
    }
}